package com.bysc.joinservice.handler;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bysc.baseservice.config.RabbitmqConfig;
import com.bysc.baseservice.handler.BaiYunException;
import com.bysc.commonutils.ResultCode;
import com.bysc.commonutils.constant.MessageConstant;
import com.bysc.commonutils.constant.RedisConstant;
import com.bysc.commonutils.enums.ActivityEnum;
import com.bysc.commonutils.utils.DateUtil;
import com.bysc.commonutils.vo.CmsActivity;
import com.bysc.joinservice.controller.JoinActivityController;
import com.bysc.joinservice.entity.JoinActivity;
import com.bysc.joinservice.service.JoinActivityService;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.List;

import static com.bysc.baseservice.config.RabbitmqConfig.EXCHANGE_TOPICS_ACTIVITY;
import static com.bysc.baseservice.config.RabbitmqConfig.ROUTINGKEY_ACTIVITY_JOIN;


@Component
public class ReceiveHandler {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private JoinActivityService joinActivityService;


    //监听队列
    @RabbitListener(queues = {RabbitmqConfig.QUEUE_INFORM_ACTIVITY_QUEUE})
    public void receive_queue(String idAndUserId, Message message, Channel channel) {
        try {
            //将idAndUserId分割
            String[] split = idAndUserId.split(":");
            String id = split[0];
            String userId = split[1];
            //判断名额的状态位
            String status = JoinActivityController.status.get(id);
            if ("0".equals(status)) {
                redisTemplate.opsForSet().remove("activity:queue:"+id, userId);
                throw new BaiYunException(ResultCode.ERROR, "名额已满");
            }
            //判断是否提交
            Boolean aBoolean1 = redisTemplate.opsForSet().isMember("activity:submit:" + id, userId);
            if (aBoolean1) {
                //已提交报名表
                redisTemplate.opsForSet().remove("activity:queue:"+id, userId);
                throw new BaiYunException(ResultCode.ERROR, MessageConstant.ALREADY_SUBMIT);
            }
            //判断是否报名
            Boolean aBoolean = redisTemplate.opsForSet().isMember("activity:join:" + id, userId);
            if (aBoolean) {
                //报名过
                redisTemplate.opsForSet().remove("activity:queue:"+id, userId);
                throw new BaiYunException(ResultCode.ERROR, MessageConstant.ALREADY_REGISTERED);
            }
            Long size = redisTemplate.opsForList().size(RedisConstant.ACTIVITY_NUMBER + id);
            if (size <= 0) {
                //人满了
                redisTemplate.convertAndSend("activity", id + ":0");
                redisTemplate.opsForSet().remove("activity:queue:"+id, userId);
                throw new BaiYunException(ResultCode.ERROR, "名额已满");
            }
            //删除排队k,加入报名k,rightPop名额k
            redisTemplate.opsForSet().add("activity:join:"+id, userId);
            redisTemplate.opsForSet().remove("activity:queue:"+id, userId);
            redisTemplate.opsForList().rightPop(RedisConstant.ACTIVITY_NUMBER + id);
            rabbitTemplate.convertAndSend(EXCHANGE_TOPICS_ACTIVITY, ROUTINGKEY_ACTIVITY_JOIN, idAndUserId, new MessagePostProcessor() {
                @Override
                public Message postProcessMessage(Message message) throws AmqpException {
                    // 设置延迟时间
                    message.getMessageProperties().setExpiration(String.valueOf(15 * 60 * 1000));
                    return message;
                }
            });
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            try {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }

    }

    /**
     * 延迟队列
     * @param idAndUserId
     * @param message
     * @param channel
     */
    @RabbitListener(queues = {RabbitmqConfig.QUEUE_INFORM_DDL})
    public void receive_DDL(String idAndUserId, Message message, Channel channel) {
        try {
            //将idAndUserId分割
            String[] split = idAndUserId.split(":");
            String id = split[0];
            String userId = split[1];
            //查询报名表,判断是否提交报名表
            JoinActivity joinActivity = joinActivityService.getOne(new QueryWrapper<JoinActivity>().eq("user_id", userId));
            if (joinActivity == null) {
                //返还名额k,删除报名k
                redisTemplate.opsForZSet().remove("activity:join:"+id, userId);
                redisTemplate.opsForList().leftPush(RedisConstant.ACTIVITY_NUMBER + id, id);
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            try {
                channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
                System.out.println("延迟队列发生错误：" + idAndUserId);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}